<template>
    <div>
        <!-- 面包屑导航 -->
        <el-breadcrumb separator="/">
            <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
            <el-breadcrumb-item>权限管理</el-breadcrumb-item>
            <el-breadcrumb-item>角色列表</el-breadcrumb-item>
        </el-breadcrumb>
        <!--table表格在浏览器本身渲染差-->
        <!--<el-table row-key="id" :data="roleList" border>-->
        <el-table :data="roleList" border>
            <!-- 添加展开列 -->
            <el-table-column type="expand">
                <!--栅格-->
                <template slot-scope="scope">
                    <el-row :class="['bdbottom',i1==0?'bdtop':'','vcenter']" v-for="(item1,i1) in scope.row.children" :key="item1.id">
                        <!-- 渲染一级权限 -->
                        <el-col :span="5">
                            <el-tag closable @close="deleteRoles(scope.row, item1.id)">
                                {{item1.authName}}
                            </el-tag>
                            <i class="el-icon-caret-right"></i>
                        </el-col>
                        <!-- 渲染二，三级权限 -->
                        <el-col :span="19">
                            <!-- 通过for循环嵌套渲染二级权限  -->
                            <el-row :class="[i2==0?'':'bdtop' ,'vcenter']" v-for="(item2,i2) in item1.children" :key="item2.id">
                                <el-col :span="6">
                                    <el-tag type="success" closable @close="deleteRoles(scope.row, item2.id)">
                                        {{item2.authName}}
                                    </el-tag>
                                    <i class="el-icon-caret-right"></i>
                                </el-col>
                                <el-col :span="18">
                                    <el-tag closable @close="deleteRoles(scope.row, item3.id)" type="warning" v-for="(item3) in item2.children" :key="item3.id">
                                        {{item3.authName}}
                                    </el-tag>
                                </el-col>
                            </el-row>
                        </el-col>
                    </el-row>
                </template>
            </el-table-column>
            <el-table-column type="index"></el-table-column>
            <el-table-column label="角色名称" prop="roleName"></el-table-column>
            <el-table-column label="角色描述" prop="roleDesc"></el-table-column>
            <el-table-column label="操作" width="300px">
                <template slot-scope="scope">
                    <el-button size="mini" type="primary" icon="el-icon-edit">编辑</el-button>
                    <el-button size="mini" type="danger" icon="el-icon-delete">删除</el-button>
                    <el-button size="mini" @click="showSetRightDialog(scope.row)" type="warning" icon="el-icon-setting">分配权限</el-button>
                </template>
            </el-table-column>
        </el-table>

        <!-- 分配权限对话框 -->
        <el-dialog title="分配权限" :visible.sync="setRightDialogVisible" width="50%" @close="setRightDialogClose">
            <!-- 树形组件
            show-checkbox:显示复选框
            node-key:设置选中节点对应的值
            default-expand-all:是否默认展开所有节点
            :default-checked-keys 设置默认选中项的数组
            ref:设置引用 -->
            <el-tree
                    :data="rightsList"
                    :props="treeProps"
                    show-checkbox
                    node-key="id"
                    default-expand-all
                    :default-checked-keys="defKeys"
                    ref="treeRef">
            </el-tree>
            <span slot="footer" class="dialog-footer">
        <el-button @click="setRightDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="allotRights">确 定</el-button>
    </span>
        </el-dialog>
    </div>
</template>

<script>
    export default {

        props: [],

        components: {},

        data() {
            return {
                roleList: [],
                setRightDialogVisible: false,
                rightsList: [],
                //树形控件的属性绑定对象
                treeProps: {
                    //通过label设置树形节点文本展示authName
                    label: 'authName',
                    //设置通过children属性展示子节点信息
                    children: 'children'
                },
                //设置树形控件中默认选中的内容
                defKeys: [],
                //保存正在操作的角色id
                roleId:'',
            };
        },

        watch: {},

        created() {
            this.getRoleList();
        },

        mounted() {

        },

        methods: {
            async getRoleList(){
                const {data:res} = await this.$http.get('roles');
                //如果返回状态为异常状态则报错并返回
                 if (res.meta.status !== 200)
                     return this.$message.error('获取角色列表失败');
                 //如果返回状态正常，将请求的数据保存在data中
                 this.roleList = res.data
            },
            async deleteRoles(role,rightId){
                //弹窗提示用户是否要删除
                const confirmResult = await this.$confirm('请问是否要删除该权限','删除提示',{
                    confirmButtonText:'确认删除',
                    cancelButtonText:'取消',
                    type:'warning'
                }).catch(err=>err);
                //如果用户点击确认，则confirmResult 为'confirm'
                //如果用户点击取消, 则confirmResult获取的就是catch的错误消息'cancel'
                if(confirmResult != "confirm"){
                    return this.$message.info("已经取消删除")
                }

                //用户点击了确定表示真的要删除
                //当发送delete请求之后，返回的数据就是最新的角色权限信息
                const {data:res} = await this.$http.delete(`roles/${role.id}/rights/${rightId}`);
                if (res.meta.status !== 200)
                    return this.$message.error('删除角色权限失败');

                //无需再重新加载所有权限
                //只需要对现有的角色权限进行更新即可
                role.children = res.data
                // this.getRoleList();

            },
            async showSetRightDialog(role) {
                this.roleId = role.id;
                //获取所有权限的数据
                const {data:res} = await this.$http.get('rights/tree');
                //如果返回状态为异常状态则报错并返回
                if (res.meta.status !== 200)
                    return this.$message.error('获取权限树失败');
                //如果返回状态正常，将请求的数据保存在data中
                this.rightsList = res.data;
                // 递归获取三级节点的Id
                this.getLeafKeys(role, this.defKeys);
                //当点击分配权限按钮时，展示对应的对话框
                this.setRightDialogVisible = true;
            },
            // 通过递归的形式，获取角色下所有三级权限的id，并保存到 defKeys 数组中
            getLeafKeys(node, arr) {
                // 如果当前 node 节点不包含 children 属性，则是三级节点
                if (!node.children) {
                    return arr.push(node.id)
                }
//              node.children.forEach(item => this.getLeafKeys(item, arr))
                node.children.forEach((item)=>{
                    return this.getLeafKeys(item, arr)
                })
            },
            setRightDialogClose() {
                //当用户关闭树形权限对话框的时候，清除掉所有选中状态
                this.defKeys = []
            },
            async allotRights() {
                //当用户在树形权限对话框中点击确定，将用户选择的
                //权限发送请求进行更新

                //获取所有选中及半选的内容
                const keys = [
                    ...this.$refs.treeRef.getCheckedKeys(),
                    ...this.$refs.treeRef.getHalfCheckedKeys()
                ];
                //将数组转换为 , 拼接的字符串
                const idStr = keys.join(',');

                //发送请求完成更新
                const { data: res } = await this.$http.post(
                    `/roles/${this.roleId}/rights`,
                    { rids:idStr }
                );
                if (res.meta.status !== 200)
                    return this.$message.error('分配权限失败');

                this.$message.success("分配权限成功");
                this.getRoleList();
                //关闭对话框
                this.setRightDialogVisible = false;
            }
        },

        computed: {}
    };
</script>

<style lang="scss" type="text/scss" scoped>
    .el-table{
        margin-top: 20px;
    }
    .el-tag {
        margin: 7px;
        user-select: none;
    }

    .bdtop {
        border-top: 1px solid #eee;
    }

    .bdbottom {
        border-bottom: 1px solid #eee;
    }

    .vcenter {
        display: flex;
        align-items: center;
    }
</style>
